#ifndef SEQUENCE_CORPUS_READER_H
#define SEQUENCE_CORPUS_READER_H

#include <string>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <boost/shared_ptr.hpp>

#include "gzstream.h"
#include "cmdline.h"

class SequenceCorpusReader
{
public:
//	struct Segment
//	{
//		friend std::ostream& operator<<(std::ostream&, const Segment&);
//		Segment(size_t l, size_t s, size_t e)
//			: label(l), start(s), end(e) {}
//		size_t label;
//		size_t start;
//		size_t end;
//	};
//	typedef boost::shared_ptr<Segment> SegmentPtr;
	typedef std::map<std::pair<size_t,size_t>,size_t> SegmentLabelling;
	typedef boost::shared_ptr<SegmentLabelling> SegmentLabellingPtr;
	struct Entry
	{
		Entry() : gold(new SegmentLabelling) {}
		friend std::ostream& operator<<(std::ostream&, const Entry&);
		int start_label;
		int end_label;
		SegmentLabellingPtr gold;
		std::vector<std::vector<std::set<std::string> > > features_chart;
	};
	typedef boost::shared_ptr<Entry> EntryPtr;

public:
	SequenceCorpusReader(boost::shared_ptr<Parameters> p);
	~SequenceCorpusReader();

	EntryPtr next();
	size_t labels() const { return myNumLabels; }
	void reset();
	bool eof() { return myEOF; }
	size_t order() const { return mySemiOrder; }

protected:
	EntryPtr get_tokens(igzstream &in);

private:
	bool myHaveGold;
	bool myEOF;
	igzstream myInputFile;
	size_t mySemiOrder;
	size_t myNumLabels;
};
typedef boost::shared_ptr<SequenceCorpusReader> SequenceCorpusReaderPtr;

#endif
